package com.tbi.graphcolouring.testers;

import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.border.TitledBorder;

import org.jfree.chart.ChartPanel;

import com.tbi.algorithm.AlgorithmDataCollectorDecorator;
import com.tbi.algorithm.ConfigurableGenethicAlgorithm;
import com.tbi.graphcolouring.BaseGraph;
import com.tbi.graphcolouring.GraphFactory;
import com.tbi.graphcolouring.algorithmconfiguration.creator.RandomPopulationCreator;
import com.tbi.graphcolouring.algorithmconfiguration.crosser.MultiPointCrosser;
import com.tbi.graphcolouring.algorithmconfiguration.evaluator.RepairEvaluator;
import com.tbi.graphcolouring.algorithmconfiguration.mutator.SinglePointMutator;
import com.tbi.graphcolouring.algorithmconfiguration.selector.ExponentialRankingSelector;
import com.tbi.graphcolouring.algorithmconfiguration.selector.GaussianRankingSelector;
import com.tbi.graphcolouring.algorithmconfiguration.stopper.GenerationStopper;
import com.tbi.graphcolouring.algorithmconfiguration.stopper.NoImprovementStopper;
import com.tbi.graphcolouring.datacollector.AlgorithmStopDataCollector;

@SuppressWarnings("serial")
public class AlgorithmTest extends JFrame {

	public static void main(String[] args) {
//		BaseGraph graph = GraphFactory.load("graphs/queen25_160_5.col");
//		BaseGraph graph = GraphFactory.load("graphs/queen36_290_7.col");
		BaseGraph graph = GraphFactory.load("graphs/queen64_728_9.col");
//		BaseGraph graph = GraphFactory.load("graphs/queen256_12640_x.col");

		ConfigurableGenethicAlgorithm algorithm = new ConfigurableGenethicAlgorithm();
		
		algorithm.setCrosser(new MultiPointCrosser());
		algorithm.setEvaluator(new RepairEvaluator(graph));
//		algorithm.setEvaluator(new PunishmentEvaluator(graph));
		algorithm.setMutator(new SinglePointMutator());
		algorithm.setPopulationCreator(new RandomPopulationCreator(100));
//		algorithm.setSelector(new ExponentialRankingSelector());
		algorithm.setSelector(new GaussianRankingSelector());
		algorithm.setStopper(new NoImprovementStopper(100));
//		algorithm.setStopper(new GenerationStopper(2000));
		
		AlgorithmDataCollectorDecorator algorithmDataCollector = new AlgorithmDataCollectorDecorator(algorithm);
		
		final AlgorithmStopDataCollector dataCollector = new AlgorithmStopDataCollector();
		algorithmDataCollector.setAlgorithmStopDataCollector(dataCollector);
		
		algorithmDataCollector.doIt(graph);
		
		System.out.println("Average: "+dataCollector.getAverageEntity(dataCollector.getGenerations()));
		System.out.println("Best rating in last generation: "+dataCollector.getBestEntity(dataCollector.getGenerations()).rating);
		System.out.println("Best's colours in last generation: "+Arrays.toString(dataCollector.getBestEntity(dataCollector.getGenerations()).colors));
		System.out.println("Best entity ever: "+dataCollector.getBestEver());
		
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					AlgorithmTest frame = new AlgorithmTest(dataCollector);
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 * @param dataCollector 
	 * @param randomCounter 
	 */
	public AlgorithmTest(AlgorithmStopDataCollector dataCollector) {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(10, 10, 1300, 700);
		ChartPanel cp = PlotPanel.getInstance(dataCollector);
		cp.setBorder(new TitledBorder(null, "Chart", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		setContentPane(cp);
		
		addKeyListener(new KeyListener() {
			public void keyTyped(KeyEvent arg0) { } 
			public void keyReleased(KeyEvent arg0) { }
			
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
					System.exit(0);
				}
			}
		});
	}
}
